package de.westranger.forex.trading.analysis;

import static org.junit.Assert.assertEquals;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;

import org.junit.Test;

import de.westranger.forex.trading.genetic.CSVBasedContentResolver;
import de.westranger.forex.trading.genetic.ContentResolver;
import de.westranger.forex.trading.genetic.allel.fitness.ProfitManager;
import de.westranger.forex.trading.genetic.allel.operator.TerminalSymbol;

public class LinearRegressionTest {

	@Test
	public void testLinearRegression(){
		final double[] xValues = new double[]{20.0,16,15,16,13,10};
		final double[] yValues = new double[]{0,3,7,4,6,10};
		final double[] result = LinearRegression.computeRegression(xValues, yValues);
		
		assertEquals(19.73,result[0],0.005);
		assertEquals(-0.98,result[1],0.005);
	}
	
	
	@Test
	public void testLinearRegressionNormalize(){
		final double[] xValues = new double[]{20.0,16,15,16,13,10};
		final double[] yValues = new double[]{0,3,7,4,6,10};
		final double[] result = LinearRegression.computeRegression(xValues, yValues);
		
		assertEquals(19.73,result[0],0.005);
		assertEquals(-0.98,result[1],0.005);
		
//		final double[] norm = LinearRegression.normalize(xValues, yValues, result);
//		for(int i=0;i<norm.length;i++){
//			System.out.println(xValues[i]+"\t"+norm[i]);
//		}
	}
	
	@Test
	public void testExmapleData(){
//		double[] data = new double[] { 1.3108, 1.3108, 1.3091, 1.3089,
//				1.3081, 1.3052, 1.3002, 1.2985, 1.2985, 1.2956, 1.2847, 1.2823,
//				1.2842, 1.2815, 1.2816, 1.2816, 1.2818, 1.2798, 1.2815, 1.2862,
//				1.2965, 1.2986, 1.2986, 1.2935, 1.2923, 1.2907, 1.2931, 1.293,
//				1.3074, 1.3074 }; 
		double[] yValues = new double[] { 1.3108, 1.3108, 1.3091, 1.3089,
				1.3081, 1.3052, 1.3002, 1.2985, 1.2985, 1.2956, 1.2847, 1.2823,
				1.2842, 1.2815, 1.2816, 1.2816, 1.2818, 1.2798}; 
		
		final double[] xValues = new double[yValues.length];
		
		for(int i=0;i< yValues.length;i++){
			xValues[i] = i;
		}
		
		final double[] result = LinearRegression.computeRegression(xValues, yValues);
		
		System.out.println("function: " + LinearRegression.printFunction(result));
		
		final double[] norm = LinearRegression.normalize(xValues, yValues, result);
		
		double min = Double.MAX_VALUE;
		double max = Double.MIN_VALUE;
		
		for(double x:norm){
			min = Math.min(min, x);
			max = Math.max(max, x);
		}
		
		final double[] chanMin = new double[]{result[0]+(min*1.01),result[1]};
		final double[] chanMax = new double[]{result[0]+(max*1.01),result[1]}; 
		
		System.out.println("function min: " + LinearRegression.printFunction(chanMin));
		System.out.println("function max: " + LinearRegression.printFunction(chanMax));
		
	}
	
	@Test
	public void testComputeTrendsFortimeSeries() throws IOException, ParseException{
		final ContentResolver conRes = new CSVBasedContentResolver("./data/mt4_validation_mql_indicator_1.csv.gz");
		final BufferedWriter bw = new BufferedWriter(new FileWriter("out.csv")); 
		final int len = 10;
		double[] values = new double[len];

		bw.append("TIME;");
		for(int j=0;j<len;j++){
			bw.append("ATTR"+j+';');
		}
		bw.append('\n');
		
		for (int i = len; i < conRes.getValueCount(); i++) {
			for(int j=0;j<len;j++){
				values[j] = conRes.resolve(TerminalSymbol.LOW.getValue(),i-len+j);
			}
			
			double max = Double.MIN_VALUE;
			for(double d:values){
				max = Math.max(max, d);
			}			
			for(int j=0;j<len;j++){
				values[j]/=max;
			}
			
			double min = Double.MAX_VALUE;
			for(double d:values){
				min = Math.min(min, d);
			}
			
			for(int j=0;j<len;j++){
				values[j]-=min;
			}			
			
			bw.append(Long.toString((long)conRes.resolve(TerminalSymbol.TIME.getValue(),i))+";");
			for(double d:values){
				bw.append(d*10000.0+";");
			}
			bw.append('\n');
		}
		bw.close();
	}	
}
